<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
 *      [PinTuXiu] (C)2001-2099 ONightjar.com Pintuxiu.com.
 *      This is NOT a freeware, use is subject to license terms
*/
define('CENSOR_SUCCEED', 0);
define('CENSOR_BANNED', 1);
define('CENSOR_MODERATED', 2);
define('CENSOR_REPLACED', 3);
class censor_api{

	public function getcensorbyid($cid){
		return load_db('censor')->findBy('censor_id',$cid);
	}

	public function getcensorwords($page,$pagesize){
		return load_db('censor')->search($page,$pagesize);
	}

	public function getcensorwordscache(){
		return load_db('censor')->getCensorWords();
	}

	public function getallcensorwords(){
		return load_db('censor')->findAll();
	}
	public function findAllOrderTypeFind(){
		return load_db('censor')->findAllOrderTypeFind();
	}
	public function deleteCensorByid($id){
		$censordb = load_db('censor');
		$result = $censordb->delete(array('censor_id'=>$id));
		if($result) $censordb->build_cache_censor();
		return $result;
	}

	public function addcensor($data){
		$censordb = load_db('censor');
		$result = $censordb->create($data);
		if($result) $censordb->build_cache_censor();
		return $result;
	}

	public function updatecensorcache(){
		return load_db('censor')->build_cache_censor();
	}

	public function clearallcensor(){
		return load_db('censor')->truncate();
	}

	public function updateCensorByid($id,$update){
		$censordb = load_db('censor');
		$result = $censordb->update(array('censor_id'=>$id),$update);
		if($result) $censordb->build_cache_censor();
		return $result;
	}

	public function updateCensorByFind($find,$update){
		$censordb = load_db('censor');
		$result = $censordb->update(array('find'=>$find),$update);
		return $result;
	}

	public function getcensortypebyid($cid){
		return load_db('censor/censortype')->findBy('id',$cid);
	}

	public function getcensortypebytypename($typename){
		return load_db('censor/censortype')->findBy('typename',$typename);
	}

	public function getcensortypes($page,$pagesize){
		return load_db('censor/censortype')->search($page,$pagesize);
	}
	public function getallcensortypes(){
		return load_db('censor/censortype')->findAll();
	}

	public function deleteCensortypeByid($id){
		$censordb = load_db('censor/censortype');
		$result = $censordb->delete(array('id'=>$id));
		$db = load_db('censor');
		$result = $db->update(array('type'=>$id),array('type'=>'1'));
		if($result) $db->build_cache_censor();
		return $result;
	}

	public function addcensortype($data){
		$censordb = load_db('censor/censortype');
		$result = $censordb->create($data);
		return $result;
	}

	public function updateCensortypeByid($id,$update){
		$censordb = load_db('censor/censortype');
		$result = $censordb->update(array('id'=>$id),$update);
		return $result;
	}

	function highlight($message, $badwords_regex) {
		$message = preg_replace($badwords_regex, '<span style="color: red;">\\1</span>', $message);
		return $message;
	}

	public function censorcheck(&$message, $modword = NULL) {
		$limitnum = 500;
		$censor_words = $this->getcensorwordscache();
		$this->words_found = array();
		$bbcodes = 'b|i|color|size|font|align|list|indent|email|hide|quote|code|free|table|tr|td|img|swf|attach|payto|float';
		if(is_array($censor_words['banned']) && !empty($censor_words['banned'])) {
			foreach($censor_words['banned'] as $banned_words) {
				if(preg_match_all($banned_words, @preg_replace(array("/\[($bbcodes)=?.*\]/iU", "/\[\/($bbcodes)\]/i"), '', $message), $matches)) {
					$this->words_found = $matches[0];
					$this->words_found = array_unique($this->words_found);
					$message = $this->highlight($message, $banned_words);
					return CENSOR_BANNED;
				}
			}
		}
		if(is_array($censor_words['mod']) && !empty($censor_words['mod'])) {
			if($modword !== NULL) {
				$message = preg_replace($censor_words['mod'], $modword, $message);
			}
			foreach($censor_words['mod'] as $mod_words) {
				if(preg_match_all($mod_words, @preg_replace(array("/\[($bbcodes)=?.*\]/iU", "/\[\/($bbcodes)\]/i"), '', $message), $matches)) {
					$this->words_found = $matches[0];
					$message = $this->highlight($message, $mod_words);
					$this->words_found = array_unique($this->words_found);
					return CENSOR_MODERATED;
				}
			}
		}
		if(!empty($censor_words['filter'])) {
			$i = 0;
			while($find_words = array_slice($censor_words['filter']['find'], $i, $limitnum)) {
				if(empty($find_words)) break;
				$replace_words = array_slice($censor_words['filter']['replace'], $i, $limitnum);
				$i += $limitnum;
				$message = preg_replace($find_words, $replace_words, $message);
			}
			return CENSOR_REPLACED;
		}
		return CENSOR_SUCCEED;
	}


	public function censor(&$message, $modword = NULL) {
		$pz = &get_instance();
		if(!$pz->sysperm['ignorecensor']){
			$result = $this->censorcheck($message, $modword);
			if($result==CENSOR_BANNED) {
				$wordbanned = implode(', ', $this->words_found);
				return sprintf(lang('500_word_banned', 'tip'),$wordbanned);
			}
		}
		if(($pz->memperm['allowposturl'] == 0 || $pz->memperm['allowposturl'] == 2)&&(!$pz->isadmin && !$pz->iseditor)) {
			$urllist = self::get_url_list($message);
			if(is_array($urllist[1])) foreach($urllist[1] as $key => $val) {
				if(!$val = trim($val)) continue;
				if(!$this->iswhitelist($val)) {
					if($pz->memperm['allowposturl'] == 0) {
						return lang('post_url_nopermission', 'tip');
					} elseif($pz->memperm['allowposturl'] == 2) {
						$message = str_replace('[url]'.$urllist[0][$key].'[/url]', $urllist[0][$key], $message);
						$message = preg_replace(
								array(
										"@\[url=[^\]]*?".preg_quote($urllist[0][$key],'@')."[^\]]*?\](.*?)\[/url\]@is",
										"@href=('|\")".preg_quote($urllist[0][$key],'@')."\\1@is",
										"@\[url\]([^\]]*?".preg_quote($urllist[0][$key],'@')."[^\]]*?)\[/url\]@is",
								),
								array(
										'\\1',
										'',
										'\\1',
								),
								$message);
					}
				}
			}
		}
		return false;
	}

	private function iswhitelist($host) {
		static $iswhitelist = array();
		if(isset($iswhitelist[$host])) {
			return $iswhitelist[$host];
		}
		$hostlen = strlen($host);
		$iswhitelist[$host] = false;
		$setting = load_api('setting')->getSetting('share');
		$data = $setting['domainwhitelist'] ? explode("\r\n", $setting['domainwhitelist']) : array();

		if(is_array($data)) foreach($data as $val) {
			$domainlen = strlen($val);
			if($domainlen > $hostlen) {
				continue;
			}
			if(substr($host, -$domainlen) == $val) {
				$iswhitelist[$host] = true;
				break;
			}
		}
		if($iswhitelist[$host] == false) {
			$iswhitelist[$host] = $host == $_SERVER['HTTP_HOST'];
		}
		return $iswhitelist[$host];
	}

	public static function get_url_list($message) {
		$return = array();
		(strpos($message, '[/img]') || strpos($message, '[/flv]')) && $message = preg_replace("/\[img[^\]]*\]\s*([^\[\<\r\n]+?)\s*\[\/img\]|\[flv[^\]]*\]\s*([^\[\<\r\n]+?)\s*\[\/flv\]/is", '', $message);
		if(preg_match_all("/((https?|ftp|gopher|news|telnet|rtsp|mms|callto|bctp|thunder|qqdl|synacast){1}:\/\/|www\.)[^ \[\]\"']+/i", $message, $urllist)) {
			foreach($urllist[0] as $key => $val) {
				$val = trim($val);
				$return[0][$key] = $val;
				if(!preg_match('/^http:\/\//is', $val)) $val = 'http://'.$val;
				$tmp = parse_url($val);
				$return[1][$key] = $tmp['host'];
				if($tmp['port']){
					$return[1][$key] .= ":$tmp[port]";
				}
			}
		}
		return $return;
	}
}